cmake_minimum_required(VERSION 3.7)

project(
        rd_cpp
        VERSION 1.0
        # DESCRIPTION "C++ implementation of JetBrains IPC"
        # HOMEPAGE_URL "https://github.com/jetbrains/rd"
        LANGUAGES CXX
)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# Add path for custom modules.
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(utils)

set(CMAKE_INSTALL_LIBS "${CMAKE_CURRENT_LIST_DIR}/export/libs")
set(CMAKE_INSTALL_PUBLIC_HEADER "${CMAKE_CURRENT_LIST_DIR}/export/include")
set(CMAKE_INSTALL_PUBLIC_HEADER_THIRDPARTY "${CMAKE_INSTALL_PUBLIC_HEADER}/thirdparty")

if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic")
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG")
    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2")
    add_compile_options(
            -Wno-unused-variable
            -Wno-unknown-pragmas            # autogenerated msvc pragmas
    )
    if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
        if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "7.0.0")
            message(FATAL_ERROR "Insufficient clang version")
        endif ()
        if (CMAKE_BUILD_TYPE MATCHES "Debug")
            option(USE_ADDRESS_SANITIZER "Use address sanitizer to troubleshoot invalid allocations" ON)
        else ()
            option(USE_ADDRESS_SANITIZER "Use address sanitizer to troubleshoot invalid allocations" OFF)
        endif ()
        if (USE_ADDRESS_SANITIZER)
            set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -g")
        endif()
    endif ()
    if (MINGW)
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj")
    endif ()
elseif (MSVC)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
    add_definitions(-D_CRT_SECURE_NO_WARNINGS)
    add_compile_options(
            /wd4996     # POSIX name is deprecated
    )
endif ()

set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

option(ENABLE_TESTS_OPTION "Global enable test" ON)
option(INSTALL_GTEST OFF)

set(RD_CORE_CPP_ENABLE_TESTS ${ENABLE_TESTS_OPTION} CACHE BOOL "Enable core tests." FORCE)
set(RD_FRAMEWORK_CPP_ENABLE_TESTS ${ENABLE_TESTS_OPTION} CACHE BOOL "Enable framework tests." FORCE)
set(RD_GEN_CPP_ENABLE_TESTS ${ENABLE_TESTS_OPTION} CACHE BOOL "Enable gen tests." FORCE)

# pch are not working on clang for now, need investigation
if (MSVC)
    option(ENABLE_PCH_HEADERS "Enable precompiled headers" ON)
else ()
    option(ENABLE_PCH_HEADERS "Enable precompiled headers" OFF)
endif ()
if (ENABLE_PCH_HEADERS)
    set(PCH_CPP_OPT pch.cpp)
else ()
    set(PCH_CPP_OPT "")
endif ()

option(RD_STATIC "Compile RD as static library" OFF)

add_subdirectory(thirdparty)
add_subdirectory(src)

if (ENABLE_TESTS_OPTION)
    if (NOT EXISTS "${PROJECT_SOURCE_DIR}/demo")
        message(FATAL_ERROR "Run 'gradlew generateEverything' in rd root to generate missing folders.")
    endif ()
    add_subdirectory(googletest)
    add_subdirectory(demo)
endif ()
